package cn.liulin.java8.stream;

import cn.liulin.java8.pojo.Dish;
import com.alibaba.fastjson.JSON;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * cn.liulin.java8.stream$
 * 流分为中间操作和终端操作
 * 中间操作得到流
 * 终端操作得到结果
 * @author ll
 * @date 2021-10-13 14:14:52
 **/
public class StreamUse {
    public static void main(String[] args) {
//        useOne();
//        useTwo();
//        useThree();
//        useFour();
//        useFive();
//        useSix();
//        useSeven();
//        useEight();
//        useNine();
//        useTen();
        useEleven();
    }

    private static void useEleven() {
        List<String> strings = Arrays.asList("hello", "world");
        List<String> collect = strings.stream()
                .map(d -> d.split(""))
                //把一个流中的每个值都换成另一个流，然后把所有的流连接起来成为一个流
                .flatMap(Arrays::stream)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(JSON.toJSONString(collect));
    }

    private static void useTen() {
        List<String> strings = Arrays.asList("hello", "world");
        List<Stream<String>> collect = strings.stream()
                .map(d -> d.split(""))
                .map(Arrays::stream)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(JSON.toJSONString(collect));
    }

    private static void useNine() {
        List<String> strings = Arrays.asList("hello", "world");
        List<String[]> collect = strings.stream()
                .map(d -> d.split(""))
                .distinct()
                .collect(Collectors.toList());
        System.out.println(JSON.toJSONString(collect));
    }

    private static void useEight() {
        Dish dish1 = new Dish("hasd", true);
        Dish dish2 = new Dish("g", false);
        Dish dish3 = new Dish("asdf", false);
        Dish dish4 = new Dish("dfg", true);
        List<Dish> menu = Arrays.asList(dish1, dish2, dish3, dish4);
        List<Integer> collect = menu.stream()
                .map(Dish::getName)
                .map(String::length)
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    private static void useSeven() {
        List<String> strings = Arrays.asList("java8", "in", "action");
        List<Integer> collect = strings.stream()
                .map(String::length)
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    private static void useSix() {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 2, 5, 6);
        List<Integer> collect = integers.stream()
                .filter(i -> i % 2 == 0)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    private static void useFive() {
        Dish dish1 = new Dish("hasd", true);
        Dish dish2 = new Dish("g", false);
        Dish dish3 = new Dish("asdf", false);
        Dish dish4 = new Dish("dfg", true);
        List<Dish> menu = Arrays.asList(dish1, dish2, dish3, dish4);
        List<Dish> collect = menu.stream()
                .filter(Dish::isVegetarian)
                .collect(Collectors.toList());
        System.out.println(JSON.toJSONString(collect));
    }

    private static void useFour() {
        Dish dish1 = new Dish("hasd", 100);
        Dish dish2 = new Dish("g", 200);
        Dish dish3 = new Dish("asdf", 300);
        Dish dish4 = new Dish("dfg", 400);
        List<Dish> menu = Arrays.asList(dish1, dish2, dish3, dish4);
        List<String> collect = menu.stream()
                .filter(d -> d.getCalories() > 200)
                .map(Dish::getName)
                .limit(3)
                .collect(Collectors.toList());
        System.out.println(JSON.toJSONString(collect));
    }

    private static void useThree() {
        Dish dish1 = new Dish("hasd", 100);
        Dish dish2 = new Dish("g", 200);
        Dish dish3 = new Dish("asdf", 300);
        Dish dish4 = new Dish("dfg", 400);
        List<Dish> menu = Arrays.asList(dish1, dish2, dish3, dish4);
        List<String> collect = menu.stream()
                .filter(d -> {
                    System.out.println("start filter");
                    return d.getCalories() > 200;
                })
                .map(d -> {
                    System.out.println("start map");
                    return d.getName();
                })
                .limit(3)
                .collect(Collectors.toList());
        System.out.println(JSON.toJSONString(collect));
    }

    private static void useTwo() {
        Dish dish1 = new Dish("hasd");
        Dish dish2 = new Dish("g");
        Dish dish3 = new Dish("asdf");
        Dish dish4 = new Dish("dfg");
        List<Dish> menu = Arrays.asList(dish1, dish2, dish3, dish4);
        List<String> collect = menu.stream().map(Dish::getName).collect(Collectors.toList());
        System.out.println(JSON.toJSONString(collect));
    }

    private static void useOne() {
        List<String> strings = Arrays.asList("java8", "in", "action");
        Stream<String> stream = strings.stream();
        stream.forEach(System.out::println);
        //stream has already been operated upon or closed
        //流已被操作或关闭
        //流只能使用一次
        stream.forEach(System.out::println);
    }
}
